home *** CD-ROM | disk | FTP | other *** search
- /*
- * OpenURL -- A Workbech/CLI frontend for "openurl.library".
- *
- * Written by Thomas Aglassinger <agi@sbox.tu-graz.ac.at>
- * Placed in the public domain.
- *
- * Based on material provided by Troels Walsted Hansen <troels@thule.no>
- */
-
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <libraries/openurl.h>
- #include <intuition/intuition.h>
-
- #include <string.h>
-
- #include "SmartReadArgs.h"
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <proto/openurl.h>
-
- static const char *version = "\0$VER: OpenURL 1.1 " __AMIGADATE__;
-
- #define TEMPLATE "URL/A,NOSHOW/S,NOFRONT/S,NEWWIN/S,NOLAUNCH/S,FILE/S"
- enum
- {
- A_URL, A_NOSHOW, A_NOFRONT, A_NEWWIN, A_NOLAUNCH, A_FILE, A_MAX
- };
-
- /* Maximum length an URL can get according to w3c. Currently, CLI
- * imposes even a smaller limit of 512. */
- #define MAXIMUM_URL_LENGTH 1024
-
- struct Library *OpenURLBase;
-
- #define OPENURL_VERSION 1 /* Minimum version of openurl.library */
- #define OPENURL_VERSION_STR "1" /* Used by error message */
-
- #define MAXIMUM_ERROR_LENGTH 120 /* Size of buffer for error messages */
-
- /* Some shit necessary because C standard libraries suck */
- ULONG ulong_max(ULONG a, ULONG b)
- {
- if (a > b)
- {
- return a;
- }
- else
- {
- return b;
- }
- }
-
- /* Main function
- *
- * Note that the startup code of SAS/c sets argc=0 when started from
- * workbench. This fact is used to auto-enable FILE in such a case.
- */
- int main(int argc, char *argv[])
- {
- int return_code = RETURN_FAIL;
-
- /* Error code from dos.library's IoErr() */
- LONG error_code = 0;
- /* Description of the action failed. If error_code is 0, only this
- * text is displayed. Otherwise, also the DOS error message is
- * appended. */
- STRPTR error_cause = NULL;
-
- /* Workbench startup message or NULL if started from CLI */
- struct WBStartup *wb_startup = NULL;
-
- /* Buffer for error messages. This is not allocated dynamically because
- * then it might not exist in case of no memory. */
- UBYTE error_buffer[MAXIMUM_ERROR_LENGTH] =
- {NULL};
-
- if ((OpenURLBase = OpenLibrary("openurl.library", OPENURL_VERSION)))
- {
- struct SmartArgs smart_args =
- {NULL};
- LONG args[A_MAX] =
- {0};
-
- /* The URL passed to URL_Open() */
- STRPTR real_url = NULL;
-
- /* The fully qualified filename, if any */
- STRPTR filename = NULL;
-
- /* Prepare argument parsing */
- smart_args.sa_Template = TEMPLATE;
- smart_args.sa_Parameter = args;
- smart_args.sa_FileParameter = A_URL;
- smart_args.sa_Window = "CON:////OpenURL/AUTO/CLOSE/WAIT";
-
- return_code = RETURN_ERROR;
-
- /* Auto-enable FILE switch when started from WB */
- if (argc == 0)
- {
- wb_startup = (struct WBStartup *) argv;
- args[A_FILE] = 1;
- }
-
- /* Parse arguments, either from Workbench or CLI */
- error_code = SmartReadArgs(wb_startup, &smart_args);
-
- /* Allocate string buffers. This reduces stack usage and also
- * makes the string buffers being checked by Mungwall.
- *
- * Yes, this wastes some memory if FILE is not set, but makes the
- * error handling easier.
- *
- * Yes, we could use a 2K buffer with filename = real_url + 1024 to
- * use only one allocation. This however would reduce the possibilty
- * for out-of-bounds checks for the end of one/beginning of the
- * other string. */
- if (error_code == 0)
- {
- /* Allocate string buffers */
- real_url = AllocVec(MAXIMUM_URL_LENGTH, MEMF_ANY);
- filename = AllocVec(MAXIMUM_URL_LENGTH, MEMF_ANY);
- if ((real_url == NULL) || (filename == NULL))
- {
- /* Not enough memory */
- SetIoErr(ERROR_NO_FREE_STORE);
- error_code = IoErr();
- }
- }
-
- if (error_code == 0)
- {
- if (args[A_FILE])
- {
- /* Expand the filename to a fully qualified URL */
- BPTR lock = Lock((STRPTR) args[A_URL], ACCESS_READ);
-
- if (lock != NULL)
- {
- if (NameFromLock(lock, filename, MAXIMUM_URL_LENGTH))
- {
- strcpy(real_url, "file://localhost/");
- strncat(real_url, filename, MAXIMUM_URL_LENGTH);
- }
- else
- {
- error_cause = "Error obtaining full filename";
- error_code = IoErr();
- }
- UnLock(lock);
- }
- else
- {
- error_cause = "Error opening input file";
- error_code = IoErr();
- }
- }
- else
- {
- /* Simply use the URL passed in arguments, assuming it is
- * an already fully qualified URL of any protocol. Possible
- * errors are now treated by the browser. */
- strncpy(real_url, (STRPTR) args[A_URL], MAXIMUM_URL_LENGTH);
- }
-
- /* Make sure that the URL gets a trailing zero (just in case
- * someone passed a too long one). */
- real_url[MAXIMUM_URL_LENGTH - 1] = '\0';
-
- if (error_code == 0)
- {
- /* Really show it */
- if (URL_Open(real_url,
- URL_Launch, !args[A_NOLAUNCH],
- URL_Show, !args[A_NOSHOW],
- URL_BringToFront, !args[A_NOFRONT],
- URL_NewWindow, args[A_NEWWIN],
- TAG_DONE))
- {
- return_code = RETURN_OK;
- }
- else
- {
- error_code = 0;
- if (args[A_NOLAUNCH])
- {
- error_cause = "Could not find browser port";
- }
- else
- {
- error_cause = "Could not launch browser";
- }
- }
- }
- }
- else
- {
- error_cause = "Error in arguments";
- }
-
- /* Free extended read args (even in case of error) */
- SmartFreeArgs(&smart_args);
-
- /* Release all other resources */
- if (filename != NULL)
- {
- FreeVec(filename);
- }
- if (real_url != NULL)
- {
- FreeVec(real_url);
- }
-
- CloseLibrary(OpenURLBase);
- }
- else
- {
- error_cause =
- "Could not find \"openurl.library\", "
- "version " OPENURL_VERSION_STR;
- }
-
- /* Create error message in error_buffer (if any) */
- if (error_code != 0)
- {
- Fault(error_code, error_cause, error_buffer, MAXIMUM_ERROR_LENGTH);
- }
- else if (error_cause != NULL)
- {
- strncpy(error_buffer, error_cause, MAXIMUM_ERROR_LENGTH - 1);
- }
-
- /* Display error message in CLI or Requester (if any) */
- if (error_buffer[0] != '\0')
- {
- if (wb_startup != NULL)
- {
- struct EasyStruct error_requester =
- {
- sizeof(struct EasyStruct),
- 0,
- "OpenURL Error",
- "%s",
- "Cancel"
- };
-
- EasyRequest(NULL, &error_requester, NULL, error_buffer);
- }
- else
- {
- FPuts(Output(), error_buffer);
- FPuts(Output(), "\n");
- }
- }
-
- return (return_code);
- }
-